package com.xhwl.centiotdata.pollingtrigger.alarm;

import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.xhwl.centiotdata.mq.producer.GeneralProducer;
import com.xhwl.centiotdata.pojo.enums.alarm.LanJuAlarmEnum;
import com.xhwl.centiotdata.pollingtrigger.ScheduleDispatcher;
import com.xhwl.centiotdata.service.cent.IDeviceCentService;
import com.xhwl.centiotdata.suppliersystem.eesd.batown.BaAccessUtil;
import com.xhwl.centiotdata.utils.HttpUtils;
import com.xhwl.centiotdata.utils.ThreadPoolUtils;
import com.xhwl.common.dto.cent.device.DeviceDTO;
import com.xhwl.common.pojo.cent.alarm.AlarmManagement;
import com.xhwl.common.query.cent.device.DevicePageQuery;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author xh_lwy
 * @description: 告警管理
 * @date 2022/2/1717:43
 */
@Slf4j
@Service
public class AlarmDispatcher implements ScheduleDispatcher {

    @Value("${alarm.lanjuUrl}")
    private String lanjuUrl;

    private static final String LAN_JU_TOPIC = "LAN_JU_TOPIC";

    @Value("${huawei3800.server}")
    private String server;

    @Value("${huawei3800.port}")
    private String port;

    @Value("${huawei3800.user}")
    private String user;

    @Value("${huawei3800.password}")
    private String password;

    @Value("${huawei3800.callback}")
    private String callback;


    @Autowired
    private IDeviceCentService iDeviceCentService;
    @Autowired
    GeneralProducer generalProducer;

    @Override
    public void doTenMinutesTask() {
        // 定时任务处理告警事件通知
//        ThreadPoolUtils.executor.execute(() -> {
//            //奥莱蓝居设备告警
//            getDeviceId(1, 8, (deviceId, projectId) -> requestLanjuData(deviceId, projectId));
//            //奥莱ba设备告警
//            getDeviceId(1, getBADeviceTypeIds(), (deviceId, projectId) -> requestBAData(deviceId, projectId));
//        });
        ThreadPoolUtils.alarmExecutor.submit(() -> keepAlive());

    }

    private interface OnGetDeviceIdCallBack {
        void request(String deviceId, Integer projectId);
    }

    private void getDeviceId(Integer projectId, Integer deviceTypeId, OnGetDeviceIdCallBack onGetDeviceIdCallBack) {
        List<Integer> list = new ArrayList<>();
        list.add(deviceTypeId);
        getDeviceId(projectId, list, onGetDeviceIdCallBack);
    }

    /**
     * 从设备中台，获取相关设备id
     *
     * @param projectId
     * @param deviceTypeIds
     * @param onGetDeviceIdCallBack
     */
    private void getDeviceId(Integer projectId, List<Integer> deviceTypeIds, OnGetDeviceIdCallBack onGetDeviceIdCallBack) {
        DevicePageQuery deviceQuery = new DevicePageQuery();
        deviceQuery.setProjectId(projectId);
        deviceQuery.setDeviceTypeIdList(deviceTypeIds);
        List<DeviceDTO> deviceList = iDeviceCentService.listDevice(null, deviceQuery);
        if (deviceList == null) {
            log.info("projectId=" + projectId + ",deviceTypeIds=" + deviceTypeIds + ",当前查询无匹配设备");
            return;
        }
        List<String> deviceIds = deviceList.stream().map(DeviceDTO::getThirdDeviceId).collect(Collectors.toList());
        deviceIds.forEach(deviceId ->
                ThreadPoolUtils.executor.execute(() ->
                        onGetDeviceIdCallBack.request(deviceId, projectId)));
    }

    /**
     * 获取蓝居设备数据，发送数据到kafka给告警模块消费
     *
     * @param deviceId
     * @param projectId
     */
    private void requestLanjuData(String deviceId, Integer projectId) {
        try {

            AlarmManagement alarmManagement = new AlarmManagement();
            lanjuUrl = String.format(lanjuUrl, deviceId);
            JSONObject jsonObject = (JSONObject) HttpUtils.doGet(lanjuUrl, null, null, new HashMap<>(), new HashMap<>());
            JSONArray jsonArray = jsonObject.getJSONArray("data");
            for (Object obj : jsonArray) {
                JSONObject dataObj = JSONObject.parseObject(obj.toString());
                //组装公共部分数据
                alarmManagement.setProjectId(projectId);
                alarmManagement.setAlarmTime(new Date());
                alarmManagement.setDeviceId(Integer.valueOf(deviceId));
                for (LanJuAlarmEnum value : LanJuAlarmEnum.values()) {
                    String name = value.name();
                    //发送所有可获取的属性
                    if (dataObj.containsKey(name)) {
                        Object o = dataObj.get(name);
                        alarmManagement.setAlarmInventoryCode(value.getCode());
                        alarmManagement.setThreshold((BigDecimal) o);
                        generalProducer.send(LAN_JU_TOPIC, JSONObject.toJSONString(alarmManagement));
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取ba数据，发送给kafka，告警模块会消费
     */
    private void requestBAData(String deviceId, Integer projectId) {
        BaAccessUtil baAccessUtil = new BaAccessUtil("http://172.50.73.250/OpenApi/Http/", "60b65d85c2724796b8da2b0dcb130417", "63b8cb5cf1784e448ad7be3a930ca6bd");
        Map<String, Object> siteTreeDetail = baAccessUtil.<Map<String, Object>>getSiteTreeDetail(deviceId);
        //处理数据。..
    }

    public List<Integer> getBADeviceTypeIds() {
        List<Integer> deviceTypeIds = new ArrayList<>();
        deviceTypeIds.add(22);
        deviceTypeIds.add(13);
        deviceTypeIds.add(30);
        deviceTypeIds.add(32);
        deviceTypeIds.add(34);
        deviceTypeIds.add(14);
        return deviceTypeIds;
    }

    private void keepAlive() {
        log.info("=======================>开始执行保活！");
        String login = HttpUtil.post("https://" + server + ":" + port + "/loginInfo/login/v1.0", JSONObject.toJSONString(new HashMap<String, Object>() {{
            put("userName", user);
            put("password", password);
        }}));
        String keepAlive = HttpUtil.get("https://" + server + ":" + port + "/common/keepAlive");
        log.info("login====================>{}keepAlive================>{}设备订阅回调请求返回====================》{}",
                JSONObject.toJSONString(login),
                JSONObject.toJSONString(keepAlive));
    }
}
